\documentclass[a4paper, 12pt]{article}

\usepackage{czech}
\usepackage[T1]{fontenc}      % T1 kodovani fontu pro babel cestinu
\usepackage[utf8]{inputenc}  % kodovani dokumentu
\usepackage{url}
\usepackage{graphicx}
\usepackage{lscape}

\begin{document}
\begin{titlepage}
% logo ZČU
\includegraphics[width=0.30 \textwidth, keepaspectratio]{fav_cmyk}

\vspace{4cm}

\begin{center}
% název práce
\huge{\textbf{Programovací techniky}}\\[1ex]

{\large Standardní semestrální práce}

\end{center}

\vfill
\begin{tabbing}
  Zpracovali:gsgfs\= Zdeněk \textsc{Janeček}\kill
  Zpracovali:\> Zdeněk \textsc{Janeček}\\
  \> Ondřej \textsc{Ptáček}\\[1ex]
  Datum: \> 10.\,prosince\,2012
\end{tabbing}
\end{titlepage}

\section{Zadání}
Firma \uv{Napětí a proud} provozuje fiktivní zdroje elektrické energie
(klasické a alternativní) a přenosovou soustavu, kterou dodává
elektrický proud firmám a domácnostem. Celkem provozuje jeden klasický
zdroj (elektrárnu) o~výkonu 150 \,MW nacházející se přibližně
uprostřed území o~velikosti $250 \cdot 250$\,Km a 10 menších
rovnoměrně rozmístěných alternativních zdrojů elektrické energie,
každý o~výkonu 10\,MW. Minimální vzdálenost těchto zdrojů je 50\,km.
Výkon elektrárny se může měnit maximálně o~10\% během jedné hodiny,
výkon alternativních zdrojů se může měnit v~intervalu 0 až 100\% během
jedné hodiny. Na daném území se dále rovnoměrně vyskytuje $1100$
odběrných míst, z~toho je 100 firem o~maximálním průměrném příkonu
1\,MW (příkon firem odpovídá diskrétnímu rovnoměrnému rozdělení na
intervalu 500\,kW až 1,5\,MW s~krokem 10\,kW, tento příkon se mění
v~závislosti na denní době) a 1000 domácností o~maximálním průměrném
příkonu 100\,kW (příkon domácností odpovídá diskrétnímu rovnoměrnému
rozdělení na intervalu 0\,kW až 200\,kW s~krokem 1\,kW, tento příkon
se mění v~závislosti na denní době). Elektrárna je přímo spojena se
150 nejbližšími odběrnými místy, každý alternativní zdroj energie je
spojen s~50 nejbližšími odběrnými místy. Každé odběrné místo je dále
spojeno s~30 dalšími nejbližšími odběrnými místy. Ztráta při přenosu
elektrické energie je 0.25\% na 1\,km vedení. Výrobní cena elektřiny
je 1,80\,Kč/kWh u~klasického zdroje, 2\,Kč/kWh u~alternativních zdrojů
energie.

Průměrný příkon domácnosti se v~průběhu dne mění dle tabulky
\ref{tab:dom} (\% z~maximálního průměrného příkonu 100\,kW).

\begin{table}
\centering
\begin{tabular}{|*{6}{l@{\hspace{30pt}}|}}
\hline
0 & 35\,\% & 8 & 90\,\% & 16 & 60\,\%\\ \hline
1 & 30\,\% & 9 & 70\,\% & 17 & 70\,\%\\ \hline
2 & 25\,\% & 10 & 50\,\% & 18 & 90\,\%\\ \hline
3 & 20\,\% & 11 & 50\,\% & 19 & 100\,\%\\ \hline
4 & 15\,\% & 12 & 60\,\% & 20 & 90\,\%\\ \hline
5 & 30\,\% & 13 & 50\,\% & 21 & 70\,\%\\ \hline
6 & 70\,\% & 14 & 50\,\% & 22 & 50\,\%\\ \hline
7 & 100\,\% & 15 & 60\,\% & 23 & 40\,\%\\
\hline
\end{tabular}
\caption{Příkon domácností}
\label{tab:dom}
\end{table}

Průměrný příkon firmy se v~průběhu dne mění dle tabulky \ref{tab:fir}
(\% z~maximálního průměrného příkonu 1\,MW)

\begin{table}
\centering
\begin{tabular}{|*{6}{l@{\hspace{30pt}}|}}
\hline
0 & 30\,\% & 8 & 90\,\% & 16 & 75\,\%\\ \hline
1 & 30\,\% & 9 & 100\,\% & 17 & 50\,\%\\ \hline
2 & 30\,\% & 10 & 100\,\% & 18 & 50\,\%\\ \hline
3 & 30\,\% & 11 & 100\,\% & 19 & 100\,\%\\ \hline
4 & 35\,\% & 12 & 85\,\% & 20 & 40\,\%\\ \hline
5 & 55\,\% & 13 & 100\,\% & 21 & 30\,\%\\ \hline
6 & 70\,\% & 14 & 100\,\% & 22 & 30\,\%\\ \hline
7 & 80\,\% & 15 & 90\,\% & 23 & 30\,\%\\
\hline
\end{tabular}
\caption{Příkon firem}
\label{tab:fir}
\end{table}

Cílem je simulovat a řídit provoz klasického zdroje, alternativních
zdrojů a přenosové soustavy tak, aby výrobní náklady a náklady na
přenos elektřiny k~zákazníkům byly minimální.

\begin{itemize}
\item Simulaci provozu celé soustavy proveďte pro dva dny ($2 \cdot
24$ hod) po hodinách
\item Začínáte v~čase 0:00 prvního dne, elektrárna běží na plný výkon
tzn. 150\,MW, alternativní zdroje na 50\% výkonu.
\end{itemize}

\subsection{Postup}
\begin{itemize}
\item připravte vstupní data (zdroje energie, odběrná místa,
vzdálenosti mezi nimi) a uložte je ve vhodném formátu (10b.).
  \begin{itemize}
  \item zdroje energie, odběrná místa -- 2b
  \item vzdálenosti
    \begin{itemize}
    \item rozměry, počet hran -- nejbližší sousedé -- 2b
    \item minimálně trojúhelníková nerovnost -- 2b
    \item příkony domácností a firem – rovnoměrné rozdělení -- 2b
    \end{itemize}
  \item vhodný formát uložení -- 2b
  \end{itemize}
\item zvolte a implementujte vhodné datové struktury pro reprezentaci
vstupních dat, důsledně zvažujte paměťovou náročnost zvolených
struktur a časovou náročnost algoritmů pro následovné výpočty (10b.)
  \begin{itemize}
  \item reprezentace vstupních dat -- 5b
  \item výpočty ekonomické náročnosti odběru pro jednotlivá odběrná místa -- 5b
  \end{itemize}
\item proveďte základní simulaci pro čas 0:00 prvního dne, vypište,
které odběrné místo je zásobováno kterým energetickým zdrojem, průběh
simulace (všechny důležité hodnoty) zapisujte na obrazovku a také do
souboru (10 b.)
  \begin{itemize}
  \item implementace, určení zdrojů pro odběrná místa -- 8b
  \item výpis (obrazovka, soubor) -- 2b
  \end{itemize}
\end{itemize}

výše popsaná část bude váš minimální výstup při kontrolním cvičení cca
v~polovině semestru.

\begin{itemize}
\item vytvořte prostředí pro snadnou obsluhu programu (menu,
ošetření vstupů) - nemusí být grafické umožněte zadání požadavku
na přidání odběrného místa a změny hodnoty příkonu odběrného
místa z~klávesnice (5b.)
  \begin{itemize}
    \item přehlednost, úplnost -- 2b
    \item zadání požadavku z~klávesnice -- 2b
    \item ošetření zadávání nesmyslných hodnot -- 1b
  \end{itemize}
\item umožněte aktuální sledování příkonu odběrného místa, jeho
zásobování elektrickou energií a sledování aktuálního výkonu
energetického zdroje (5b.)
\item proveďte simulaci pro 48 hod a vygenerujte do souborů
následující statistiky (uložte je do vhodných souborů -- 10b.)
  \begin{itemize}
    \item přehled jednotlivých en. zdrojů s~uvedením výkonu
    v~jednotlivých hodinách simulace, uveďte výkon spotřebovaný v~síti
    a výkon, který případně nebyl spotřebován, uveďte souhrn
    pro všechny energetické zdroje.
    \item přehled jednotlivých odběrných míst s~uvedením příkonu
v~jednotlivých hodinách simulace, a spotřebovanou energií od
    počátku simulace (v~kW i Kč), uveďte souhrnná čísla.
  \end{itemize}
\item vytvořte dokumentační komentáře ve zdrojovém textu programu
a vygenerujte programovou dokumentaci (Javadoc). (10b.)
  \begin{itemize}
    \item třídy -- 2b
    \item atributy -- 2b
    \item metody -- 5b
    \item je vygenerovaný JavaDoc -- 1b
  \end{itemize}
\item vytvořte kvalitní dále rozšiřitelný kód - kontrola dle webové aplikace
(bude doplněno() (10b.)
  \begin{itemize}
    \item minus 1 bod za vážnější chybu, při 6 a více chybách nutno opravit.
  \end{itemize}
\end{itemize}

V~rámci dokumentace: připojte zadání (1b.), popište analýzu problému (6b.),
popište návrh programu např. pomocí jednoduchého UML diagramu (6b.),
vytvořte přívětivou uživatelskou dokumentaci (5b.), zhodnoťte celou práci,
vytvořte závěr (2b.).

\section{Řešení programu}
\subsection{Specifikace}
\suppressfloats[t]
Ze zadání je třeba ujasnit některé věci. První
věc je tedy jak se vlastně bude proud distribuovat. Jisté je, že každý
zdroj energie bude v~určité hodině produkovat určité množství energie.

Každé odběrné místo ale dostane nižší množství energie dané ztrátou
na 1\,km. Těch zdrojů bude ale více. Cílem je vybrat nejvýhodnější zdroj
pro elektrárenskou společnost.

Ideální zdroj je předně ten nejbližší, ale není tomu, úplně tak.
Musí se zohlednit také cena, protože výroba energie u~alternativního
zdroje je vyšší než u~klasického zdroje.

V~každém čase je odběr energie různý. Každé odběrné místo
mění svůj příkon relativně k~počáteční hodnotě. Tato hodnota
by měla vzniknout tak aby celkově tvořili rovnoměrné rozložení
s~průměrnou hodnotou.

U~regulace výkonu elektrárny se potýkáme se základním problémem.
Jaká bude zátěž elektrárny za hodinu, aby jsme nastavili její výkon
pro co nejmenší ztráty. My to naštěstí víme, protože se příkony
mění podle tabulky. Jakmile spočítáme příkony do budoucna
(se započtením ztrát) stačí nastavit výkony elektráren na trochu
větší hodnotu.

Celou dobu se musí sledovat zatížení jednotlivých elektráren,
jakmile je jedna přetížena, musí se zvolit jiná výhodnější.
Pořadí, jak budou voleny alternativní zdroje se musí zjistit
již při načítání sítě.

\begin{landscape}
\begin{figure}
\centering
\includegraphics[height=\textheight]{uml/class_diagram.pdf}
\caption{UML diagram tříd}\label{fig:umlclass}
\end{figure}
\end{landscape}

\subsection{Analýza}
\subsubsection{Simulace}
Jedná se o~grafovou úlohu. Pro účel snadné manipulace s~daty,
jsem se rozhodl pro statickou třídu \texttt{DataGuru}.
Tato třída zajišťuje uložení a následné poskytování instancí.
Uložení do vnitřní datové struktury (znamená seznamy \texttt{ArrayList})
zajišťuje metoda \texttt{nactiDataSite(String file)}.

Každá část programu má nyní k~dispozici seznam míst a elektráren,
který se dá komfortně procházet. V~tomto seznamu (poli) jsou uloženy
příslušné instance -- \texttt{OdberneMisto} pro domácnosti a
\texttt{ZdrojEnergie} pro zdroje. Oba tyto typy uchovávají
seznam svých sousedů, ale nikoli jako instance, ale pouze jejich
id. Id je totiž současně indexem do příslušného pole.

Průchod grafem v~metodě \texttt{calcNetworkStart()} je proveden
pro každou elektrárnu zvlášť.
Je to klasický Dijkstrův algoritmus. Ukládám si každé
nové nalezené místo. Lépe řečeno, místu přidám do jeho seznamu
aktuální nejkratší vzdálenost ke zpracovávané elektrárně.

Pro naše potřeby jsme použili vlastní implementaci grafu. Celá
distribuční síť je rozdělená do odběrných míst a zdrojů energie.
Instance uchovává staticky třída \texttt{DataGuru}.
Podívejte se tedy na obrázek \ref{fig:umlclass}.

Při startu aplikace se načtou informace z~vnějšího souboru, pak
se vypočtou distanční tabulky pro zdroje a odběrná místa.
K~tomu se používá statická metoda \texttt{calculateDistances()} ze třídy
\texttt{DataGuru}. Z~této tabulky lze pak v~konstantním čase
dostat vzdálenost mezi dvěma nejbližšími sousedy.

Je žádané aby aplikace běžela ve dvou rozdílných režimech:
Interaktivní, který
očekává pokyny uživatele a jednoduchý terminálový, pro odstranění
nechtěných symbolů výstupu. Jednoduchý režim nevyžaduje popis, protože
využívá standardní vstup/výstup. Interaktivní režim musí běžet ve
vlastním vlákně. Zajistit současný vstup a výstup na terminál vyžaduje
určitou režii. Běhová smyčka vlákna každých 200\,ms kontroluje zda na
vstupu čeká nějaký symbol a pokud ne, tak se znovu uspí.

Vždy běží simulační vlákno, které zajišťuje změnu světa na další
hodinu. To obnáší další běhovou smyčku, kterou lze kdykoli
pozastavit, nebo zcela zastavit.

Vrátím se ale k~distribuci. Jakmile se změní hodina, zavolá
simulační vlákno metodu \texttt{setReport(String s)}.
Ta zaprvé zajistí vypočtení hodnot zátěží a uloží statistiky.
Při výpočtu zátěží se současně vyhodnotý, zda není nějaký zdroj
přetížen a nastavý se nový. Od zavolání \texttt{calcNetworkStart()}
máme u~každého místa uložena dvě pole \texttt{powDists} a
\texttt{powSuppliers}. Indexy zase odpovídají Id elektrárny.
Vzdálenost je nekonečná, pokud nevede do tohoto místa
nejbližší cesta z~elektrárny. Ve druhém je uložena celočíselná
hodnota o~jaký zdroj se jedná.

Nejvíce nás ale zajímá jak bude měnit hodnoty do budoucna.

Hodnoty příkonů pro následující hodinu uchováme v~poli
\texttt{futurePrikon} ve třídě \texttt{Simulator}. Počítáme
je nějak takto:
\begin{verbatim}
  futurePrikon = prikony[(time + 1) % 24] * prikon
\end{verbatim}

Pole \texttt{prikony} uchovává koeficienty mezi nulou a jedničkou,
které určují procentuální hodnotu z~počáteční hodnoty. Číslo
\texttt{prikon} je počáteční hodnota.

\subsubsection{Generování dat}
Veškeré uložení dat zajišťuje třída \texttt{ArrayList}. Důvod je prostý, počet
uložených dat se mění a potřebujeme k~nim přistupovat v~co nejkratším čase.
Pro proměnné atributy souřadnic, typu místa a pole sousedů byla vytvořena
třída Krajina.

Nejdříve jsme tedy vygenerovali ve tříde Odběratele souřadnice \emph{x} a
\emph{y} pomocí metody \texttt{Math.random()}, poté byl vytvořen test
který zajistil, aby se souřadnice nemohly opakovat. Souřadnice hlavní a
alternativních elektráren jsou dány staticky.

Poté bylo potřeba vypočítat jednotlivé vzdálenosti od elektráren do
míst. Tento výpočet byl proveden pomocí pythagorovy věty. Jakmile jsme
měli vzdálenosti, bylo nutné je seřadit kvůli hledání nejbližších
sousedů každého odběrného místa a elektraren. Ve třídě RazeníDomu jsme
použili \emph{Heapsort} se složitostí O(n log n).

A~poté už jsme mohli vyhledávat a přiřazovat jednotlivé sousedy ve
třídách \texttt{PridejMista}, \texttt{SpojElec} pro elektrárny a
odběrná místa. Pro každou elektrárnu jsme tedy vygenerovali 50
nejbližších sousedů kromě hlavní která jich měla 150 a pro každé
odběrné místo minimalně 30 nejbližších sousedů. Důležité bylo si také
uvědomit, že se jedná o~neorientovaný graf, tudiž se při každém
přiřazení museli oba sousedé k~sobě zapsat do pole.

Typy míst jsou přiřazeny z~vygenerovaného souboru, kde 0 označuje 
domácnost a 1 označuje firmu. Podle tohoto typu jsme přiřazovaly ID.
Nulté ID označuje hlavní elektrárnu poté od 1 do 10 jsou alternativní
elektrárny, dále následuji až do 1010 domácnosti a od 1010 do 1110 firmy. 
Vysledek celeho generačního programu byl tedy poté zavolán v~Applikační
třídě a nasledně vytvořen vstupní soubor \texttt{vstup.txt} ve tvaru
který byl navrhnut na začatku projektu (viz soubor \texttt{sample\_data}).

\subsection{Design}
Celá aplikace běží na JVM\footnote{Java Virtual Machine} verze 1.7 a
používá její standardní knihovnu. Používáme zejména třídy z~balíčků
\emph{java.lang}, \emph{java.io} a \emph{java.util}.

\begin{figure}
\framebox{\textsf{sample\_data}}
\begin{verbatim}
MISTA
6
0;180;50;1;2
1;120;70;0;3
0;202;72;0;5
0;30;120;1;4
1;100;160;3;5
0;115;210;4;2
HL
125;125;1;2;4
ALT
2
80;80;0;1
170;170;4;5
\end{verbatim}
\caption{Vzorový datový soubor}\label{fig:datafile}
\end{figure}

Data načítáme z~textového souboru jako například soubor na obrázku
\ref{fig:datafile}. Ten se předává jako parametr (viz manuál).

Generování dat bylo provedeno samostatně. UML diagram aplikace
je na obrázku \ref{fig:umlgen}.

\begin{landscape}
\begin{figure}
\centering
\includegraphics[width=1.6\textwidth]{uml/class_diagram_gen.pdf}
\caption{UML diagram tříd generující pod-aplikace}\label{fig:umlgen}
\end{figure}
\end{landscape}

Každý blok definuje co popisuje. Jsou tam tedy 3 typy a to HL, ALT a
MISTA. HL popisuje hlavní elektrárnu, ALT popisuje alternativní zdroje
energie a MISTA popisuje odběrná místa. Za každým identifikátorem
následuje počet položek a pak jejich výpis.

První typ MISTA obsahuje \emph{id} položky
daného typu. To je číslo značící zda se jedná o~firmu (1), či
o~domácnost (0). Pak následují souřadnice X a Y. Další položky označují
sousedská odběrná místa, v~pořadí $0, 1, \ldots, n$, tak jak byly
nalezeny v~souboru. U~typů HL a ALT jsou to také odběrná místa (položky
MISTA).

Aplikace poběží v~konzolovém režimu a bude využívat ASCII escape
sekvence jako nástroj pro barvení a přesun kurzoru. Tato technika
je obecně známá ve všech linuxových emulátorech terminálu co jsem
zkoušel. Jedinou výjimkou je CMD.EXE v~systému Windows. Zvláštní je to,
že velmi starý DOS (COMMAND.COM) je normálně zná.

Protože standardní čtení z~terminálu zablokuje veškerý vstup a
výstup, vyřešil jsem to samostatně běžícím vláknem, které
každých 200 milisekund kontroluje zda leží něco na vstupu.
Kromě aplikačního vlákna, běží zde ještě třetí, které každé 3
vteřiny zvyšuje čas a mění svět.

\section{Uživatelský manuál}
V~této části rozeberu ovládání celé aplikace. Pokud jste nikdy
nepouštěli aplikaci v~Javě pokračujte ve čtení dále. Ti ostatní
mohou klidně přeskočit úvod.

K~běhu potřebujete běhové prostředí Javy. Tomu se říká Java Virtual
Machine, které pravděpodobně již na svém počítači máte, pokud ne,
tak v~případě systému Windows stáhněte instalační balíček ze stránek
\url{java.com}. V~případě Linuxu sáhněte po otevřené implementaci
OpenJDK. Určitě se bude nacházet ve Vašem repositáři.

Protože se jedná čistě o~konzolovou aplikaci, je třeba jí spustit
z~příkazového interpretu. Aplikaci nejspíše dostanete jako archiv JAR.
Přesuňte se do složky s~archivem aplikace (např. \texttt{power-control-pt.jar})
a připravte zdrojová data (např. \texttt{data.csv}). Nyní stačí zadat:

\begin{verbatim}
  java -jar power-control-pt.jar -f vstup.txt
\end{verbatim}

Ještě je možné spustit s~parametrem \texttt{-q}, kdy běží v~jednoduchém
režimu bez textového prostředí. Výstupní soubor se statistikou se vytvoří
v~aktuální složce s~názvem \texttt{stats.csv}.

\subsection{Interaktivní režim}
Jakmile se objeví modrá obrazovka znamená to, že jste v~interaktivním
režimu. Aplikace nyní běží donekonečna v~cyklu dne. Poslouchá ale naše
pokyny. Tabulka \ref{tab:ret} shrnuje všechny možné pokyny. Po každém
příkazu stačí stisknout ENTER. Po nějakém čase náš příkaz zmizí, ale
na vstupu stále čeká. Funguje i backspace.

K~dispozici jsou dvě obrazovky (obrázky \ref{fig:main} a \ref{fig:det}).
První slouží  jako nápověda a na 
detailním pohledu lze sledovat aktuální vytížení a další informace.

\begin{figure}
  \centering
  \includegraphics[width=\textwidth]{main}
  \caption{Hlavní obrazovka}
  \label{fig:main}
\end{figure}

\begin{figure}
  \centering
  \includegraphics[width=\textwidth]{det}
  \caption{Detailní výpis}
  \label{fig:det}
\end{figure}

\begin{table}
\centering
\begin{tabular}{|c|c|}
\hline
zkratka & význam\\ \hline\hline
q & vypne aplikaci\\ \hline
1 & přepne na Souhrn\\ \hline
2 & přepne na Detailní zobrazení\\ \hline
m\# & změní na místo číslo \#\\ \hline
z\# & změní na zdroj číslo \#\\ \hline
p & pozastaví/spustí simulaci\\ \hline
a$\#_1$,$\#_2$ & upraví příkon id $\#_1$ na hodnotu $\#_2$\\ \hline
n\{f,d\} & přidá firmu \emph{f}, domácnost \emph{d}\\ \hline
t\# & přesune na čas \#\\
\hline
\end{tabular}
\caption{Řídící řetězce pro interaktivní režim.}
\label{tab:ret}
\end{table}

\section{Závěr}
\paragraph{Zdeněk Janeček} Při psání této práce jsme zažili poprvé práci
ve dvou lidech. Aby jsme předešli problémům, založil jsem tedy SVN
repositář na Google Code. Dostal jsem nové zkušenosti při dělení práce.

\paragraph{Ondřej Ptáček} Tato práce byla opravdu novou zkušeností,
jelikož jsem se s~programováním poprvé setkal až zde na vysoké škole,
proto byla tato úloha pro mě značně obtížná. Hodně prvků jsem se musel
doučovat sám v~průběhu řešení tohoto problému a také mi to vzalo spoustu
času u~ostatních předmětů. Pevně doufám, že tento ztrávený čas nebyl
zbytečný pro další studium tohoto oboru.

\newpage
\tableofcontents
\listoffigures
\listoftables
\end{document}
